/**
 * ReportGear(2011)
 */
package net.abbp.report.model.cell.style;

import java.awt.Color;
import java.util.Map;
import java.util.WeakHashMap;

/**
 * 单元格边框样式
 * 
 * @version 1.0 2011-3-10
 * @author <a herf="lexloo@gmail.com">lexloo</a>
 * @since Report 1.0
 */
public class BorderStyle {
    // 边框样式缓存
    private static Map<BorderStyle, BorderStyle> cachedBorderStyle = new WeakHashMap<BorderStyle, BorderStyle>();
    /**
     * 默认单元格边框样式
     */
    public static BorderStyle DEFAULT_STYLE = BorderStyle.getInstance();

    /**
     * 无边框
     */
    public static final int NO_BORDERS = 0;
    /**
     * 外部边框
     */
    public static final int EXTERNAL_BORDERS = 1;
    /**
     * 内部线
     */
    public static final int INSIDE_BORDERS = 2;
    /**
     * 上
     */
    public static final int TOP_BORDER = 3;
    /**
     * 左
     */
    public static final int LEFT_BORDER = 4;
    /**
     * 下
     */
    public static final int BOTTOM_BORDER = 5;
    /**
     * 右
     */
    public static final int RIGHT_BORDER = 6;
    /**
     * 垂直线
     */
    public static final int VERTICAL_BORDER = 7;
    /**
     * 水平线
     */
    public static final int HORIZONTAL_BORDER = 8;

    private Color bottomColor = Color.BLACK;
    private int bottomStyle = 0;
    private Color horizentalColor = Color.BLACK;
    private int horizentalStyle = 0;
    private Color leftColor = Color.BLACK;
    private int leftStyle = 0;
    private Color rightColor = Color.BLACK;
    private int rightStyle = 0;
    private Color topColor = Color.BLACK;
    private int topStyle = 0;
    private Color verticalColor = Color.BLACK;
    private int verticalStyle = 0;

    /**
     * @return 获取单元格边框样式实例
     */
    public static BorderStyle getInstance() {
        return BorderStyle.getInstance(0, Color.BLACK, 0, Color.BLACK, 0, Color.BLACK, 0, Color.BLACK, 0, Color.BLACK,
                0, Color.BLACK);
    }

    /**
     * 获取单元格边框样式实例
     * 
     * @param topStyle
     *            上边框类型
     * @param topColor
     *            上边框颜色
     * @param leftStyle
     *            左边框类型
     * @param leftColor
     *            左边框颜色
     * @param bottomStyle
     *            下边框类型
     * @param bottomColor
     *            下边框颜色
     * @param rightStyle
     *            右边框类型
     * @param rightColor
     *            右边框颜色
     * @param horizentalStyle
     *            水平线类型
     * @param horizentalColor
     *            水平线颜色
     * @param verticalStyle
     *            垂直线类型
     * @param verticalColor
     *            垂直线颜色
     * @return 单元格边框样式实例
     */
    public static BorderStyle getInstance(int topStyle, Color topColor, int leftStyle, Color leftColor,
            int bottomStyle, Color bottomColor, int rightStyle, Color rightColor, int horizentalStyle,
            Color horizentalColor, int verticalStyle, Color verticalColor) {

        final BorderStyle tmpStyle = new BorderStyle(topStyle, topColor, leftStyle, leftColor, bottomStyle,
                bottomColor, rightStyle, rightColor, horizentalStyle, horizentalColor, verticalStyle, verticalColor);

        final BorderStyle borderStyle = BorderStyle.cachedBorderStyle.get(tmpStyle);

        if (borderStyle != null) {
            return borderStyle;
        }

        BorderStyle.cachedBorderStyle.put(tmpStyle, tmpStyle);

        return tmpStyle;
    }

    /**
     * 构造器
     */
    public BorderStyle() {
    }

    /**
     * 构造器
     * 
     * @param topStyle
     *            上边框类型
     * @param topColor
     *            上边框颜色
     * @param leftStyle
     *            左边框类型
     * @param leftColor
     *            左边框颜色
     * @param bottomStyle
     *            下边框类型
     * @param bottomColor
     *            下边框颜色
     * @param rightStyle
     *            右边框类型
     * @param rightColor
     *            右边框颜色
     */
    public BorderStyle(int topStyle, Color topColor, int leftStyle, Color leftColor, int bottomStyle,
            Color bottomColor, int rightStyle, Color rightColor) {

        this.topStyle = topStyle;
        this.topColor = topColor;
        this.leftStyle = leftStyle;
        this.leftColor = leftColor;
        this.bottomStyle = bottomStyle;
        this.bottomColor = bottomColor;
        this.rightStyle = rightStyle;
        this.rightColor = rightColor;
    }

    /**
     * 构造器
     * 
     * @param topStyle
     *            上边框类型
     * @param topColor
     *            上边框颜色
     * @param leftStyle
     *            左边框类型
     * @param leftColor
     *            左边框颜色
     * @param bottomStyle
     *            下边框类型
     * @param bottomColor
     *            下边框颜色
     * @param rightStyle
     *            右边框类型
     * @param rightColor
     *            右边框颜色
     * @param horizentalStyle
     *            水平线类型
     * @param horizentalColor
     *            水平线颜色
     * @param verticalStyle
     *            垂直线类型
     * @param verticalColor
     *            垂直线颜色
     */
    private BorderStyle(int topStyle, Color topColor, int leftStyle, Color leftColor, int bottomStyle,
            Color bottomColor, int rightStyle, Color rightColor, int horizentalStyle, Color horizentalColor,
            int verticalStyle, Color verticalColor) {
        this(topStyle, topColor, leftStyle, leftColor, bottomStyle, bottomColor, rightStyle, rightColor);

        this.horizentalStyle = horizentalStyle;
        this.horizentalColor = horizentalColor;
        this.verticalStyle = verticalStyle;
        this.verticalColor = verticalColor;
    }

    /**
     * 应用下边框颜色
     * 
     * @param bottomColor
     *            下边框颜色
     * @return 单元格边框样式
     */
    public BorderStyle applyBottomColor(Color bottomColor) {
        return BorderStyle.getInstance(getTopStyle(), getTopColor(), getLeftStyle(), getLeftColor(), getBottomStyle(),
                bottomColor, getRightStyle(), getRightColor(), getHorizentalStyle(), getHorizentalColor(),
                getVerticalStyle(), getVerticalColor());
    }

    /**
     * 应用下边框类型
     * 
     * @param bottomStyle
     *            下边框类型
     * @return 单元格边框样式
     */
    public BorderStyle applyBottomStyle(int bottomStyle) {
        return BorderStyle.getInstance(getTopStyle(), getTopColor(), getLeftStyle(), getLeftColor(), bottomStyle,
                getBottomColor(), getRightStyle(), getRightColor(), getHorizentalStyle(), getHorizentalColor(),
                getVerticalStyle(), getVerticalColor());
    }

    /**
     * 应用水平线颜色
     * 
     * @param horizentalColor
     *            水平线颜色
     * @return 单元格边框样式
     */
    public BorderStyle applyHorizentalColor(Color horizentalColor) {
        return BorderStyle.getInstance(getTopStyle(), getTopColor(), getLeftStyle(), getLeftColor(), getBottomStyle(),
                getBottomColor(), getRightStyle(), getRightColor(), getHorizentalStyle(), horizentalColor,
                getVerticalStyle(), getVerticalColor());
    }

    /**
     * 应用水平线类型
     * 
     * @param horizentalStyle
     *            水平线类型
     * @return 单元格边框样式
     */
    public BorderStyle applyHorizentalStyle(int horizentalStyle) {
        return BorderStyle.getInstance(getTopStyle(), getTopColor(), getLeftStyle(), getLeftColor(), getBottomStyle(),
                getBottomColor(), getRightStyle(), getRightColor(), horizentalStyle, getHorizentalColor(),
                getVerticalStyle(), getVerticalColor());
    }

    /**
     * 应用左边框颜色
     * 
     * @param leftColor
     *            左边框颜色
     * @return 单元格边框样式
     */
    public BorderStyle applyLeftColor(Color leftColor) {
        return BorderStyle.getInstance(getTopStyle(), getTopColor(), getLeftStyle(), leftColor, getBottomStyle(),
                getBottomColor(), getRightStyle(), getRightColor(), getHorizentalStyle(), getHorizentalColor(),
                getVerticalStyle(), getVerticalColor());
    }

    /**
     * 应用左边框类型
     * 
     * @param leftStyle
     *            左边框类型
     * @return 单元格边框样式
     */
    public BorderStyle applyLeftStyle(int leftStyle) {
        return BorderStyle.getInstance(getTopStyle(), getTopColor(), leftStyle, getLeftColor(), getBottomStyle(),
                getBottomColor(), getRightStyle(), getRightColor(), getHorizentalStyle(), getHorizentalColor(),
                getVerticalStyle(), getVerticalColor());
    }

    /**
     * 应用右边框颜色
     * 
     * @param rightColor
     *            右边框颜色
     * @return 单元格边框样式
     */
    public BorderStyle applyRightColor(Color rightColor) {
        return BorderStyle.getInstance(getTopStyle(), getTopColor(), getLeftStyle(), getLeftColor(), getBottomStyle(),
                getBottomColor(), getRightStyle(), rightColor, getHorizentalStyle(), getHorizentalColor(),
                getVerticalStyle(), getVerticalColor());
    }

    /**
     * 应用右边框类型
     * 
     * @param rightStyle
     *            右边框类型
     * @return 单元格边框样式
     */
    public BorderStyle applyRightStyle(int rightStyle) {
        return BorderStyle.getInstance(getTopStyle(), getTopColor(), getLeftStyle(), getLeftColor(), getBottomStyle(),
                getBottomColor(), rightStyle, getRightColor(), getHorizentalStyle(), getHorizentalColor(),
                getVerticalStyle(), getVerticalColor());
    }

    /**
     * 应用上边框颜色
     * 
     * @param topColor
     *            上边框颜色
     * @return 单元格边框样式
     */
    public BorderStyle applyTopColor(Color topColor) {
        return BorderStyle.getInstance(getTopStyle(), topColor, getLeftStyle(), getLeftColor(), getBottomStyle(),
                getBottomColor(), getRightStyle(), getRightColor(), getHorizentalStyle(), getHorizentalColor(),
                getVerticalStyle(), getVerticalColor());
    }

    /**
     * 应用上边框类型
     * 
     * @param topStyle
     *            上边框类型
     * @return 单元格边框样式
     */
    public BorderStyle applyTopStyle(int topStyle) {
        return BorderStyle.getInstance(topStyle, getTopColor(), getLeftStyle(), getLeftColor(), getBottomStyle(),
                getBottomColor(), getRightStyle(), getRightColor(), getHorizentalStyle(), getHorizentalColor(),
                getVerticalStyle(), getVerticalColor());
    }

    /**
     * 应用垂直线颜色
     * 
     * @param verticalColor
     *            垂直线颜色
     * @return 单元格边框样式
     */
    public BorderStyle applyVerticalColor(Color verticalColor) {
        return BorderStyle.getInstance(getTopStyle(), getTopColor(), getLeftStyle(), getLeftColor(), getBottomStyle(),
                getBottomColor(), getRightStyle(), getRightColor(), getHorizentalStyle(), getHorizentalColor(),
                getVerticalStyle(), verticalColor);
    }

    /**
     * 应用垂直线类型
     * 
     * @param verticalStyle
     *            垂直线类型
     * @return 单元格边框样式
     */
    public BorderStyle applyVerticalStyle(int verticalStyle) {
        return BorderStyle.getInstance(getTopStyle(), getTopColor(), getLeftStyle(), getLeftColor(), getBottomStyle(),
                getBottomColor(), getRightStyle(), getRightColor(), getHorizentalStyle(), getHorizentalColor(),
                verticalStyle, getVerticalColor());
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null) {
            return false;
        }
        if (getClass() != o.getClass()) {
            return false;
        }

        final BorderStyle border = (BorderStyle) o;

        return ((getTopStyle() == border.getTopStyle()) && (getBottomStyle() == border.getBottomStyle())
                && (getLeftStyle() == border.getLeftStyle()) && (getRightStyle() == border.getRightStyle())
                && (getTopColor().equals(border.getTopColor())) && (getBottomColor().equals(border.getBottomColor()))
                && (getLeftColor().equals(border.getLeftColor())) && (getRightColor().equals(border.getRightColor()))
                && (getHorizentalStyle() == border.getHorizentalStyle())
                && (getHorizentalColor().equals(border.getHorizentalColor()))
                && (getVerticalStyle() == border.getVerticalStyle()) && (getVerticalColor().equals(border
                .getVerticalColor())));
    }

    /**
     * 
     * @return 下边框颜色
     */
    public Color getBottomColor() {
        return bottomColor;
    }

    /**
     * 
     * @return 下边框类型
     */
    public int getBottomStyle() {
        return bottomStyle;
    }

    /**
     * 
     * @return 水平线颜色
     */
    public Color getHorizentalColor() {
        return horizentalColor;
    }

    /**
     * 
     * @return 水平线类型
     */
    public int getHorizentalStyle() {
        return horizentalStyle;
    }

    /**
     * 
     * @return 左边框颜色
     */
    public Color getLeftColor() {
        return leftColor;
    }

    /**
     * 
     * @return 左边框类型
     */
    public int getLeftStyle() {
        return leftStyle;
    }

    /**
     * 
     * @return 右边框颜色
     */
    public Color getRightColor() {
        return rightColor;
    }

    /**
     * 
     * @return 右边框类型
     */
    public int getRightStyle() {
        return rightStyle;
    }

    /**
     * 
     * @return 上边框颜色
     */
    public Color getTopColor() {
        return topColor;
    }

    /**
     * 
     * @return 上边框类型
     */
    public int getTopStyle() {
        return topStyle;
    }

    /**
     * 
     * @return 垂直线颜色
     */
    public Color getVerticalColor() {
        return verticalColor;
    }

    /**
     * 
     * @return 垂直线类型
     */
    public int getVerticalStyle() {
        return verticalStyle;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;

        result = prime * result + getTopStyle();
        result = prime * result + getTopColor().hashCode();
        result = prime * result + getLeftStyle();
        result = prime * result + getLeftColor().hashCode();
        result = prime * result + getBottomStyle();
        result = prime * result + getBottomColor().hashCode();
        result = prime * result + getRightStyle();
        result = prime * result + getRightColor().hashCode();
        result = prime * result + getHorizentalStyle();
        result = prime * result + getHorizentalColor().hashCode();
        result = prime * result + getVerticalStyle();
        result = prime * result + getVerticalColor().hashCode();

        return result;
    }

    public void setBottomColor(Color bottomColor) {
        this.bottomColor = bottomColor;
    }

    public void setBottomStyle(int bottomStyle) {
        this.bottomStyle = bottomStyle;
    }

    public void setHorizentalColor(Color horizentalColor) {
        this.horizentalColor = horizentalColor;
    }

    public void setHorizentalStyle(int horizentalStyle) {
        this.horizentalStyle = horizentalStyle;
    }

    public void setLeftColor(Color leftColor) {
        this.leftColor = leftColor;
    }

    public void setLeftStyle(int leftStyle) {
        this.leftStyle = leftStyle;
    }

    public void setRightColor(Color rightColor) {
        this.rightColor = rightColor;
    }

    public void setRightStyle(int rightStyle) {
        this.rightStyle = rightStyle;
    }

    public void setTopColor(Color topColor) {
        this.topColor = topColor;
    }

    public void setTopStyle(int topStyle) {
        this.topStyle = topStyle;
    }

    public void setVerticalColor(Color verticalColor) {
        this.verticalColor = verticalColor;
    }

    public void setVerticalStyle(int verticalStyle) {
        this.verticalStyle = verticalStyle;
    }

    @Override
    public String toString() {
        return "topStyle = " + getTopStyle() + ",topColor = " + getTopColor() + ",leftStyle = " + getLeftStyle()
                + ",leftColor = " + getLeftColor() + ",bottomStyle = " + getBottomStyle() + ",bottomColor = "
                + getBottomColor() + ",rightStyle = " + getRightStyle() + ",rightColor = " + getRightColor()
                + ",horizentalStyle = " + getHorizentalStyle() + ",horizentalColor = " + getHorizentalColor()
                + ",verticalStyle = " + getHorizentalStyle() + ",verticalColor = " + getVerticalColor();
    }
}
